#include "statelabel.h"
#include <QMouseEvent>
#include <QApplication>
#include <QScreen>

StateLabel::StateLabel(const QVector<StateData>& states,
                     const QVariant& initValue,
                     QWidget* parent)
    : QLabel(parent), m_states(states)
{
    setAlignment(Qt::AlignCenter);
    setCursor(Qt::PointingHandCursor);
    setFixedSize(32, 32); // 统一图标大小
    setCurrentValue(initValue);
}

void StateLabel::setCurrentValue(const QVariant& value) {
    if(m_currentValue == value) return;

    auto it = std::find_if(m_states.begin(), m_states.end(),
        [&value](const StateData& d){ return d.value == value; });

    if(it != m_states.end()) {
        m_currentValue = value;
        updateDisplay();
        emit valueChanged(m_currentValue);
    }
}

void StateLabel::mousePressEvent(QMouseEvent* event) {
    if(event->button() == Qt::LeftButton) {
        showStateMenu();
    }
    QLabel::mousePressEvent(event);
}

void StateLabel::showStateMenu() {
    m_menu.clear();

    // 创建菜单项
    foreach(const auto& state, m_states) {
        QAction* action = m_menu.addAction(state.icon, state.description);
        action->setData(state.value);
        action->setCheckable(true);
        action->setChecked(state.value == m_currentValue);
    }

    // 获取屏幕信息
    QPoint globalPos = mapToGlobal(QPoint(0, height()));
    QScreen* screen = QApplication::screenAt(globalPos);
    QRect screenRect = screen->availableGeometry();

    // 水平左对齐修正
    int menuWidth = m_menu.sizeHint().width();
    int rightEdge = globalPos.x() + menuWidth;
    if(rightEdge > screenRect.right()) {
        globalPos.setX(screenRect.right() - menuWidth);
    }

    // 垂直方向自适应
    if(globalPos.y() + m_menu.sizeHint().height() > screenRect.bottom()) {
        globalPos.setY(mapToGlobal(QPoint(0, 0)).y() - m_menu.sizeHint().height());
    }

    // 最终位置限制在屏幕内
    globalPos.setX(qMax(screenRect.left(), globalPos.x()));
    // 显示菜单并处理选择
    if(QAction* selected = m_menu.exec(globalPos)) {
        setCurrentValue(selected->data());
    }
}

void StateLabel::updateDisplay() {
    auto it = std::find_if(m_states.begin(), m_states.end(),
        [this](const StateData& d){ return d.value == m_currentValue; });

    if(it != m_states.end()) {
        setPixmap(it->icon.pixmap(size()));
    }
}
